/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later, * or the Apache License Version 2.0. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */ package javassist.scopedpool; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; import javassist.ClassPool; import javassist.LoaderClassPath; /** * An implementation of <code>ScopedClassPoolRepository</code>. * It is an singleton. * * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> * @version $Revision: 1.4 $ */ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository { /** The instance */ private static final ScopedClassPoolRepositoryImpl instance = new ScopedClassPoolRepositoryImpl(); /** Whether to prune */ private boolean prune = true; /** Whether to prune when added to the classpool's cache */ boolean pruneWhenCached; /** The registered classloaders */ protected Map registeredCLs = Collections .synchronizedMap(new WeakHashMap()); /** The default class pool */ protected ClassPool classpool; /** The factory for creating class pools */ protected ScopedClassPoolFactory factory = new ScopedClassPoolFactoryImpl(); /** * Get the instance. * * @return the instance. */ public static ScopedClassPoolRepository getInstance() { return instance; } /** * Singleton. */ private ScopedClassPoolRepositoryImpl() { classpool = ClassPool.getDefault(); // FIXME This doesn't look correct ClassLoader cl = Thread.currentThread().getContextClassLoader(); classpool.insertClassPath(new LoaderClassPath(cl)); } /** * Returns the value of the prune attribute. * * @return the prune. */ public boolean isPrune() { return prune; } /** * Set the prune attribute. * * @param prune a new value. */ public void setPrune(boolean prune) { this.prune = prune; } /** * Create a scoped classpool. * * @param cl the classloader. * @param src the original classpool. * @return the classpool */ public ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src) { return factory.create(cl, src, this); } public ClassPool findClassPool(ClassLoader cl) { if (cl == null) return registerClassLoader(ClassLoader.getSystemClassLoader()); return registerClassLoader(cl); } /** * Register a classloader. * * @param ucl the classloader. * @return the classpool */ public ClassPool registerClassLoader(ClassLoader ucl) { synchronized (registeredCLs) { // FIXME: Probably want to take this method out later // so that AOP framework can be independent of JMX // This is in here so that we can remove a UCL from the ClassPool as // a // ClassPool.classpath if (registeredCLs.containsKey(ucl)) { return (ClassPool)registeredCLs.get(ucl); } ScopedClassPool pool = createScopedClassPool(ucl, classpool); registeredCLs.put(ucl, pool); return pool; } } /** * Get the registered classloaders. */ public Map getRegisteredCLs() { clearUnregisteredClassLoaders(); return registeredCLs; } /** * This method will check to see if a register classloader has been * undeployed (as in JBoss) */ public void clearUnregisteredClassLoaders() { ArrayList toUnregister = null; synchronized (registeredCLs) { Iterator it = registeredCLs.values().iterator(); while (it.hasNext()) { ScopedClassPool pool = (ScopedClassPool)it.next(); if (pool.isUnloadedClassLoader()) { it.remove(); ClassLoader cl = pool.getClassLoader(); if (cl != null) { if (toUnregister == null) { toUnregister = new ArrayList(); } toUnregister.add(cl); } } } if (toUnregister != null) { for (int i = 0; i < toUnregister.size(); i++) { unregisterClassLoader((ClassLoader)toUnregister.get(i)); } } } } public void unregisterClassLoader(ClassLoader cl) { synchronized (registeredCLs) { ScopedClassPool pool = (ScopedClassPool)registeredCLs.remove(cl); if (pool != null) pool.close(); } } public void insertDelegate(ScopedClassPoolRepository delegate) { // Noop - this is the end } public void setClassPoolFactory(ScopedClassPoolFactory factory) { this.factory = factory; } public ScopedClassPoolFactory getClassPoolFactory() { return factory; } }