169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.scopedpool;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.ref.WeakReference;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.ProtectionDomain;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Iterator;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.LoaderClassPath;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException;
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A scoped class pool.
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author <a href="adrian@jboss.com">Adrian Brock</a>
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @version $Revision: 1.8 $
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ScopedClassPool extends ClassPool {
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ScopedClassPoolRepository repository;
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected WeakReference classLoader;
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected LoaderClassPath classPath;
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected SoftValueHashMap softcache = new SoftValueHashMap();
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    boolean isBootstrapCl = true;
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static {
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ClassPool.doPruning = false;
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ClassPool.releaseUnmodifiedClassFile = false;
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Create a new ScopedClassPool.
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cl
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the classloader
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param src
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the original class pool
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param repository
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the repository
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *@deprecated
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ScopedClassPool(ClassLoader cl, ClassPool src,
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ScopedClassPoolRepository repository) {
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       this(cl, src, repository, false);
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Create a new ScopedClassPool.
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cl
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the classloader
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param src
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the original class pool
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param repository
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the repository
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param isTemp
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            Whether this is a temporary pool used to resolve references
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ScopedClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository, boolean isTemp)
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       super(src);
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       this.repository = repository;
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       this.classLoader = new WeakReference(cl);
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       if (cl != null) {
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal           classPath = new LoaderClassPath(cl);
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal           this.insertClassPath(classPath);
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       }
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       childFirstLookup = true;
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       if (!isTemp && cl == null)
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       {
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          isBootstrapCl = true;
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       }
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Get the class loader
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the class loader
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassLoader getClassLoader() {
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       ClassLoader cl = getClassLoader0();
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       if (cl == null && !isBootstrapCl)
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       {
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          throw new IllegalStateException(
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                  "ClassLoader has been garbage collected");
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       }
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       return cl;
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ClassLoader getClassLoader0() {
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       return (ClassLoader)classLoader.get();
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Close the class pool
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void close() {
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.removeClassPath(classPath);
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classPath.close();
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classes.clear();
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        softcache.clear();
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Flush a class
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class to flush
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized void flushClass(String classname) {
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classes.remove(classname);
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        softcache.remove(classname);
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Soften a class
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param clazz
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized void soften(CtClass clazz) {
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (repository.isPrune())
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz.prune();
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classes.remove(clazz.getName());
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        softcache.put(clazz.getName(), clazz);
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Whether the classloader is loader
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return false always
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean isUnloadedClassLoader() {
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return false;
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Get the cached class
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class name
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the class
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected CtClass getCached(String classname) {
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = getCachedLocally(classname);
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null) {
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            boolean isLocal = false;
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ClassLoader dcl = getClassLoader0();
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (dcl != null) {
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                final int lastIndex = classname.lastIndexOf('$');
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String classResourceName = null;
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (lastIndex < 0) {
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    classResourceName = classname.replaceAll("[\\.]", "/")
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            + ".class";
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else {
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    classResourceName = classname.substring(0, lastIndex)
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            .replaceAll("[\\.]", "/")
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            + classname.substring(lastIndex) + ".class";
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                isLocal = dcl.getResource(classResourceName) != null;
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!isLocal) {
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Map registeredCLs = repository.getRegisteredCLs();
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                synchronized (registeredCLs) {
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    Iterator it = registeredCLs.values().iterator();
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    while (it.hasNext()) {
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        ScopedClassPool pool = (ScopedClassPool)it.next();
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (pool.isUnloadedClassLoader()) {
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            repository.unregisterClassLoader(pool
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                    .getClassLoader());
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            continue;
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        }
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        clazz = pool.getCachedLocally(classname);
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (clazz != null) {
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            return clazz;
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        }
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!!
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Cache a class
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class name
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param c
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the ctClass
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param dynamic
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            whether the class is dynamically generated
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void cacheCtClass(String classname, CtClass c, boolean dynamic) {
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (dynamic) {
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            super.cacheCtClass(classname, c, dynamic);
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else {
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (repository.isPrune())
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                c.prune();
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            softcache.put(classname, c);
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Lock a class into the cache
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param c
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void lockInCache(CtClass c) {
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super.cacheCtClass(c.getName(), c, false);
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Whether the class is cached in this pooled
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class name
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the cached class
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected CtClass getCachedLocally(String classname) {
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass cached = (CtClass)classes.get(classname);
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (cached != null)
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return cached;
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        synchronized (softcache) {
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return (CtClass)softcache.get(classname);
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Get any local copy of the class
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the class name
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the class
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws NotFoundException
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *             when the class is not found
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized CtClass getLocally(String classname)
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throws NotFoundException {
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        softcache.remove(classname);
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = (CtClass)classes.get(classname);
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null) {
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = createCtClass(classname, true);
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (clazz == null)
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new NotFoundException(classname);
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            super.cacheCtClass(classname, clazz, false);
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Convert a javassist class to a java class
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param ct
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the javassist class
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param loader
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *            the loader
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws CannotCompileException
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *             for any error
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throws CannotCompileException {
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // We need to pass up the classloader stored in this pool, as the
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // default implementation uses the Thread context cl.
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // In the case of JSP's in Tomcat,
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // org.apache.jasper.servlet.JasperLoader will be stored here, while
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // it's parent
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // org.jboss.web.tomcat.tc5.WebCtxLoader$ENCLoader is used as the Thread
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // context cl. The invocation class needs to
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // be generated in the JasperLoader classloader since in the case of
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // method invocations, the package name will be
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // the same as for the class generated from the jsp, i.e.
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // org.apache.jsp. For classes belonging to org.apache.jsp,
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // JasperLoader does NOT delegate to its parent if it cannot find them.
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        lockInCache(ct);
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return super.toClass(ct, getClassLoader0(), domain);
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
309