Kaynağa Gözat

reformatted.


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@298 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 18 yıl önce
ebeveyn
işleme
75776c6ffd

+ 248
- 240
src/main/javassist/scopedpool/ScopedClassPool.java Dosyayı Görüntüle

@@ -1,18 +1,18 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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.lang.ref.WeakReference;
@@ -25,249 +25,257 @@ import javassist.LoaderClassPath;
import javassist.NotFoundException;

/**
* A scoped class pool
* A scoped class pool.
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.2 $
* @version $Revision: 1.3 $
*/
public class ScopedClassPool extends ClassPool
{
protected ScopedClassPoolRepository repository;
protected WeakReference classLoader;
protected LoaderClassPath classPath;
protected SoftValueHashMap softcache = new SoftValueHashMap();
public class ScopedClassPool extends ClassPool {
protected ScopedClassPoolRepository repository;

static
{
ClassPool.doPruning = false;
ClassPool.releaseUnmodifiedClassFile = false;
}
/**
* Create a new ScopedClassPool.
*
* @param cl the classloader
* @param src the original class pool
* @param repository the repository
*/
protected ScopedClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository)
{
super(src);
this.repository = repository;
this.classLoader = new WeakReference(cl);
if (cl != null)
{
classPath = new LoaderClassPath(cl);
this.insertClassPath(classPath);
}
childFirstLookup = true;
}
protected WeakReference classLoader;

/**
* Get the class loader
*
* @return the class loader
*/
public ClassLoader getClassLoader()
{
return getClassLoader0();
}
protected LoaderClassPath classPath;

private ClassLoader getClassLoader0()
{
ClassLoader cl = (ClassLoader) classLoader.get();
if (cl == null)
throw new IllegalStateException("ClassLoader has been garbage collected");
return cl;
}
/**
* Close the class pool
*/
public void close()
{
this.removeClassPath(classPath);
classPath.close();
classes.clear();
softcache.clear();
}
protected SoftValueHashMap softcache = new SoftValueHashMap();

/**
* Flush a class
*
* @param classname the class to flush
*/
public synchronized void flushClass(String classname)
{
classes.remove(classname);
softcache.remove(classname);
}
static {
ClassPool.doPruning = false;
ClassPool.releaseUnmodifiedClassFile = false;
}

/**
* Soften a class
*
* @param clazz the class
*/
public synchronized void soften(CtClass clazz)
{
if (repository.isPrune()) clazz.prune();
classes.remove(clazz.getName());
softcache.put(clazz.getName(), clazz);
}
/**
* Create a new ScopedClassPool.
*
* @param cl
* the classloader
* @param src
* the original class pool
* @param repository
* the repository
*/
protected ScopedClassPool(ClassLoader cl, ClassPool src,
ScopedClassPoolRepository repository) {
super(src);
this.repository = repository;
this.classLoader = new WeakReference(cl);
if (cl != null) {
classPath = new LoaderClassPath(cl);
this.insertClassPath(classPath);
}
childFirstLookup = true;
}

/**
* Whether the classloader is loader
*
* @return false always
*/
public boolean isUnloadedClassLoader()
{
return false;
}
/**
* Get the class loader
*
* @return the class loader
*/
public ClassLoader getClassLoader() {
return getClassLoader0();
}

/**
* Get the cached class
*
* @param classname the class name
* @return the class
*/
protected CtClass getCached(String classname)
{
CtClass clazz = getCachedLocally(classname);
if (clazz == null)
{
boolean isLocal = false;
ClassLoader dcl = getClassLoader0();
if (dcl != null)
{
final int lastIndex = classname.lastIndexOf('$');
String classResourceName = null;
if (lastIndex < 0)
{
classResourceName = classname.replaceAll("[\\.]", "/") + ".class";
}
else
{
classResourceName = classname.substring(0, lastIndex).replaceAll("[\\.]", "/") + classname.substring(lastIndex) + ".class";
private ClassLoader getClassLoader0() {
ClassLoader cl = (ClassLoader)classLoader.get();
if (cl == null)
throw new IllegalStateException(
"ClassLoader has been garbage collected");
return cl;
}

/**
* Close the class pool
*/
public void close() {
this.removeClassPath(classPath);
classPath.close();
classes.clear();
softcache.clear();
}

/**
* Flush a class
*
* @param classname
* the class to flush
*/
public synchronized void flushClass(String classname) {
classes.remove(classname);
softcache.remove(classname);
}

/**
* Soften a class
*
* @param clazz
* the class
*/
public synchronized void soften(CtClass clazz) {
if (repository.isPrune())
clazz.prune();
classes.remove(clazz.getName());
softcache.put(clazz.getName(), clazz);
}

/**
* Whether the classloader is loader
*
* @return false always
*/
public boolean isUnloadedClassLoader() {
return false;
}

/**
* Get the cached class
*
* @param classname
* the class name
* @return the class
*/
protected CtClass getCached(String classname) {
CtClass clazz = getCachedLocally(classname);
if (clazz == null) {
boolean isLocal = false;

ClassLoader dcl = getClassLoader0();
if (dcl != null) {
final int lastIndex = classname.lastIndexOf('$');
String classResourceName = null;
if (lastIndex < 0) {
classResourceName = classname.replaceAll("[\\.]", "/")
+ ".class";
}
else {
classResourceName = classname.substring(0, lastIndex)
.replaceAll("[\\.]", "/")
+ classname.substring(lastIndex) + ".class";
}

isLocal = dcl.getResource(classResourceName) != null;
}

isLocal = dcl.getResource(classResourceName) != null;
}
if (!isLocal)
{
Map registeredCLs = repository.getRegisteredCLs();
synchronized (registeredCLs)
{
Iterator it = registeredCLs.values().iterator();
while (it.hasNext())
{
ScopedClassPool pool = (ScopedClassPool) it.next();
if (pool.isUnloadedClassLoader())
{
repository.unregisterClassLoader(pool.getClassLoader());
continue;
}
clazz = pool.getCachedLocally(classname);
if (clazz != null)
{
return clazz;
}
}
if (!isLocal) {
Map registeredCLs = repository.getRegisteredCLs();
synchronized (registeredCLs) {
Iterator it = registeredCLs.values().iterator();
while (it.hasNext()) {
ScopedClassPool pool = (ScopedClassPool)it.next();
if (pool.isUnloadedClassLoader()) {
repository.unregisterClassLoader(pool
.getClassLoader());
continue;
}

clazz = pool.getCachedLocally(classname);
if (clazz != null) {
return clazz;
}
}
}
}
}
}
// *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!!
return clazz;
}
/**
* Cache a class
*
* @param classname the class name
* @param c the ctClass
* @param dynamic whether the class is dynamically generated
*/
protected void cacheCtClass(String classname, CtClass c, boolean dynamic)
{
if (dynamic)
{
super.cacheCtClass(classname, c, dynamic);
}
else
{
if (repository.isPrune()) c.prune();
softcache.put(classname, c);
}
}
/**
* Lock a class into the cache
*
* @param c the class
*/
public void lockInCache(CtClass c)
{
super.cacheCtClass(c.getName(), c, false);
}
}
// *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!!
return clazz;
}

/**
* Cache a class
*
* @param classname
* the class name
* @param c
* the ctClass
* @param dynamic
* whether the class is dynamically generated
*/
protected void cacheCtClass(String classname, CtClass c, boolean dynamic) {
if (dynamic) {
super.cacheCtClass(classname, c, dynamic);
}
else {
if (repository.isPrune())
c.prune();
softcache.put(classname, c);
}
}
/**
* Lock a class into the cache
*
* @param c
* the class
*/
public void lockInCache(CtClass c) {
super.cacheCtClass(c.getName(), c, false);
}

/**
* Whether the class is cached in this pooled
*
* @param classname the class name
* @return the cached class
*/
protected CtClass getCachedLocally(String classname)
{
CtClass cached = (CtClass) classes.get(classname);
if (cached != null) return cached;
synchronized (softcache)
{
return (CtClass) softcache.get(classname);
}
}
/**
* Whether the class is cached in this pooled
*
* @param classname
* the class name
* @return the cached class
*/
protected CtClass getCachedLocally(String classname) {
CtClass cached = (CtClass)classes.get(classname);
if (cached != null)
return cached;
synchronized (softcache) {
return (CtClass)softcache.get(classname);
}
}

/**
* Get any local copy of the class
*
* @param classname the class name
* @return the class
* @throws NotFoundException when the class is not found
*/
public synchronized CtClass getLocally(String classname) throws NotFoundException
{
softcache.remove(classname);
CtClass clazz = (CtClass) classes.get(classname);
if (clazz == null)
{
clazz = createCtClass(classname, true);
if (clazz == null) throw new NotFoundException(classname);
super.cacheCtClass(classname, clazz, false);
}
/**
* Get any local copy of the class
*
* @param classname
* the class name
* @return the class
* @throws NotFoundException
* when the class is not found
*/
public synchronized CtClass getLocally(String classname)
throws NotFoundException {
softcache.remove(classname);
CtClass clazz = (CtClass)classes.get(classname);
if (clazz == null) {
clazz = createCtClass(classname, true);
if (clazz == null)
throw new NotFoundException(classname);
super.cacheCtClass(classname, clazz, false);
}

return clazz;
}
return clazz;
}

/**
* Convert a javassist class to a java class
*
* @param ct the javassist class
* @param loader the loader
* @throws CannotCompileException for any error
*/
public Class toClass(CtClass ct, ClassLoader loader) throws CannotCompileException
{
//We need to pass up the classloader stored in this pool, as the default implementation uses the Thread context cl.
//In the case of JSP's in Tomcat, org.apache.jasper.servlet.JasperLoader will be stored here, while it's parent
//org.jboss.web.tomcat.tc5.WebCtxLoader$ENCLoader is used as the Thread context cl. The invocation class needs to
// be generated in the JasperLoader classloader since in the case of method invocations, the package name will be
//the same as for the class generated from the jsp, i.e. org.apache.jsp. For classes belonging to org.apache.jsp,
//JasperLoader does NOT delegate to its parent if it cannot find them.
lockInCache(ct);
return super.toClass(ct, getClassLoader0());
}
/**
* Convert a javassist class to a java class
*
* @param ct
* the javassist class
* @param loader
* the loader
* @throws CannotCompileException
* for any error
*/
public Class toClass(CtClass ct, ClassLoader loader)
throws CannotCompileException {
// We need to pass up the classloader stored in this pool, as the
// default implementation uses the Thread context cl.
// In the case of JSP's in Tomcat,
// org.apache.jasper.servlet.JasperLoader will be stored here, while
// it's parent
// org.jboss.web.tomcat.tc5.WebCtxLoader$ENCLoader is used as the Thread
// context cl. The invocation class needs to
// be generated in the JasperLoader classloader since in the case of
// method invocations, the package name will be
// the same as for the class generated from the jsp, i.e.
// org.apache.jsp. For classes belonging to org.apache.jsp,
// JasperLoader does NOT delegate to its parent if it cannot find them.
lockInCache(ct);
return super.toClass(ct, getClassLoader0());
}
}

+ 29
- 21
src/main/javassist/scopedpool/ScopedClassPoolFactory.java Dosyayı Görüntüle

@@ -1,30 +1,38 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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 javassist.ClassPool;

/**
*
* A factory interface.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.2 $
* @version $Revision: 1.3 $
*/
public interface ScopedClassPoolFactory
{
ScopedClassPool create(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository);
ScopedClassPool create(ClassPool src, ScopedClassPoolRepository repository);
public interface ScopedClassPoolFactory {
/**
* Makes an instance.
*/
ScopedClassPool create(ClassLoader cl, ClassPool src,
ScopedClassPoolRepository repository);

/**
* Makes an instance.
*/
ScopedClassPool create(ClassPool src,
ScopedClassPoolRepository repository);
}

+ 32
- 27
src/main/javassist/scopedpool/ScopedClassPoolFactoryImpl.java Dosyayı Görüntüle

@@ -1,37 +1,42 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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 javassist.ClassPool;


/**
*
* An implementation of factory.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.2 $
* @version $Revision: 1.3 $
*/
public class ScopedClassPoolFactoryImpl implements ScopedClassPoolFactory
{
public ScopedClassPool create(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository)
{
return new ScopedClassPool(cl, src, repository);
}
public class ScopedClassPoolFactoryImpl implements ScopedClassPoolFactory {
/**
* Makes an instance.
*/
public ScopedClassPool create(ClassLoader cl, ClassPool src,
ScopedClassPoolRepository repository) {
return new ScopedClassPool(cl, src, repository);
}

public ScopedClassPool create(ClassPool src, ScopedClassPoolRepository repository)
{
return new ScopedClassPool(null, src, repository);
}
/**
* Makes an instance.
*/
public ScopedClassPool create(ClassPool src,
ScopedClassPoolRepository repository) {
return new ScopedClassPool(null, src, repository);
}
}

+ 80
- 71
src/main/javassist/scopedpool/ScopedClassPoolRepository.java Dosyayı Görüntüle

@@ -1,18 +1,18 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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.Map;
@@ -20,69 +20,78 @@ import java.util.Map;
import javassist.ClassPool;

/**
*
* An interface to <code>ScopedClassPoolRepositoryImpl</code>.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.2 $
* @version $Revision: 1.3 $
*/
public interface ScopedClassPoolRepository
{
void setClassPoolFactory(ScopedClassPoolFactory factory);
ScopedClassPoolFactory getClassPoolFactory();
public interface ScopedClassPoolRepository {
/**
* Records a factory.
*/
void setClassPoolFactory(ScopedClassPoolFactory factory);

/**
* Obtains the recorded factory.
*/
ScopedClassPoolFactory getClassPoolFactory();

/**
* Returns whether or not the class pool is pruned.
*
* @return the prune.
*/
boolean isPrune();

/**
* Get the prune.
*
* @return the prune.
*/
boolean isPrune();
/**
* Sets the prune flag.
*
* @param prune a new value.
*/
void setPrune(boolean prune);

/**
* Set the prune.
*
* @param prune the prune.
*/
void setPrune(boolean prune);
/**
* Create a scoped classpool
*
* @param cl the classloader
* @param src the original classpool
* @return the classpool
*/
ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src);
/**
* Create a scoped classpool.
*
* @param cl the classloader.
* @param src the original classpool.
* @return the classpool.
*/
ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src);

/**
* Finds a scoped classpool registered under the passed in classloader
* @param the classloader
* @return the classpool
*/
ClassPool findClassPool(ClassLoader cl);
/**
* Finds a scoped classpool registered under the passed in classloader.
*
* @param cl the classloader.
* @return the classpool.
*/
ClassPool findClassPool(ClassLoader cl);

/**
* Register a classloader
*
* @param ucl the classloader
* @return the classpool
*/
ClassPool registerClassLoader(ClassLoader ucl);
/**
* Register a classloader.
*
* @param ucl the classloader.
* @return the classpool.
*/
ClassPool registerClassLoader(ClassLoader ucl);

/**
* Get the registered classloaders
*
* @return the registered classloaders
*/
Map getRegisteredCLs();
/**
* Get the registered classloaders.
*
* @return the registered classloaders.
*/
Map getRegisteredCLs();

/**
* This method will check to see if a register classloader has been undeployed (as in JBoss)
*/
void clearUnregisteredClassLoaders();
/**
* This method will check to see if a register classloader has been
* undeployed (as in JBoss).
*/
void clearUnregisteredClassLoaders();

/**
* Unregisters a classpool and unregisters its classloader.
* @ClassLoader the classloader the pool is stored under
*/
void unregisterClassLoader(ClassLoader cl);
}
/**
* Unregisters a classpool and unregisters its classloader.
*
* @param cl the classloader the pool is stored under.
*/
void unregisterClassLoader(ClassLoader cl);
}

+ 169
- 188
src/main/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java Dosyayı Görüntüle

@@ -1,18 +1,18 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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;
@@ -25,182 +25,163 @@ 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.2 $
* @version $Revision: 1.3 $
*/
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));
}
/**
* Get the prune.
*
* @return the prune.
*/
public boolean isPrune()
{
return prune;
}

/**
* Set the prune.
*
* @param prune the prune.
*/
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
*
* @return 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);
}
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));
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;
}
}
}

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;
}
}

+ 219
- 228
src/main/javassist/scopedpool/SoftValueHashMap.java Dosyayı Görüntüle

@@ -1,18 +1,18 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc., 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.
*
* 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.
*/
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 2006 JBoss Inc. 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.
*
* 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.lang.ref.ReferenceQueue;
@@ -22,220 +22,211 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;


/**
* This Map will remove entries when the value in the map has been
* cleaned from garbage collection
*
* @version <tt>$Revision: 1.2 $</tt>
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* This Map will remove entries when the value in the map has been cleaned from
* garbage collection
*
* @version <tt>$Revision: 1.3 $</tt>
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
*/
public class SoftValueHashMap
extends AbstractMap
implements Map
{
private static class SoftValueRef extends SoftReference
{
public Object key;

private SoftValueRef(Object key, Object val, ReferenceQueue q)
{
super(val, q);
this.key = key;
}
private static SoftValueRef create(Object key, Object val, ReferenceQueue q)
{
if (val == null) return null;
else return new SoftValueRef(key, val, q);
}
}
public Set entrySet()
{
processQueue();
return hash.entrySet();
}

/* Hash table mapping WeakKeys to values */
private Map hash;

/* Reference queue for cleared WeakKeys */
private ReferenceQueue queue = new ReferenceQueue();
/* Remove all invalidated entries from the map, that is, remove all entries
whose values have been discarded.
*/
private void processQueue()
{
SoftValueRef ref;
while ((ref = (SoftValueRef)queue.poll()) != null) {
if (ref == (SoftValueRef) hash.get(ref.key)) {
// only remove if it is the *exact* same WeakValueRef
//
hash.remove(ref.key);
}
}
}


/* -- Constructors -- */

/**
* Constructs a new, empty <code>WeakHashMap</code> with the given
* initial capacity and the given load factor.
*
* @param initialCapacity The initial capacity of the
* <code>WeakHashMap</code>
*
* @param loadFactor The load factor of the <code>WeakHashMap</code>
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero, or if the load factor is
* nonpositive
*/
public SoftValueHashMap(int initialCapacity, float loadFactor)
{
hash = new HashMap(initialCapacity, loadFactor);
}

/**
* Constructs a new, empty <code>WeakHashMap</code> with the given
* initial capacity and the default load factor, which is
* <code>0.75</code>.
*
* @param initialCapacity The initial capacity of the
* <code>WeakHashMap</code>
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero
*/
public SoftValueHashMap(int initialCapacity)
{
hash = new HashMap(initialCapacity);
}

/**
* Constructs a new, empty <code>WeakHashMap</code> with the default
* initial capacity and the default load factor, which is
* <code>0.75</code>.
*/
public SoftValueHashMap()
{
hash = new HashMap();
}

/**
* Constructs a new <code>WeakHashMap</code> with the same mappings as the
* specified <tt>Map</tt>. The <code>WeakHashMap</code> is created with an
* initial capacity of twice the number of mappings in the specified map
* or 11 (whichever is greater), and a default load factor, which is
* <tt>0.75</tt>.
*
* @param t the map whose mappings are to be placed in this map.
* @since 1.3
*/
public SoftValueHashMap(Map t)
{
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}

/* -- Simple queries -- */

/**
* Returns the number of key-value mappings in this map.
* <strong>Note:</strong> <em>In contrast with most implementations of the
* <code>Map</code> interface, the time required by this operation is
* linear in the size of the map.</em>
*/
public int size()
{
processQueue();
return hash.size();
}

/**
* Returns <code>true</code> if this map contains no key-value mappings.
*/
public boolean isEmpty()
{
processQueue();
return hash.isEmpty();
}

/**
* Returns <code>true</code> if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
*/
public boolean containsKey(Object key)
{
processQueue();
return hash.containsKey(key);
}

/* -- Lookup and modification operations -- */

/**
* Returns the value to which this map maps the specified <code>key</code>.
* If this map does not contain a value for this key, then return
* <code>null</code>.
*
* @param key The key whose associated value, if any, is to be returned
*/
public Object get(Object key)
{
processQueue();
SoftReference ref = (SoftReference)hash.get(key);
if (ref != null) return ref.get();
return null;
}

/**
* Updates this map so that the given <code>key</code> maps to the given
* <code>value</code>. If the map previously contained a mapping for
* <code>key</code> then that mapping is replaced and the previous value is
* returned.
*
* @param key The key that is to be mapped to the given
* <code>value</code>
* @param value The value to which the given <code>key</code> is to be
* mapped
*
* @return The previous value to which this key was mapped, or
* <code>null</code> if if there was no mapping for the key
*/
public Object put(Object key, Object value)
{
processQueue();
Object rtn = hash.put(key, SoftValueRef.create(key, value, queue));
if (rtn != null) rtn = ((SoftReference)rtn).get();
return rtn;
}

/**
* Removes the mapping for the given <code>key</code> from this map, if
* present.
*
* @param key The key whose mapping is to be removed
*
* @return The value to which this key was mapped, or <code>null</code> if
* there was no mapping for the key
*/
public Object remove(Object key)
{
processQueue();
return hash.remove(key);
}

/**
* Removes all mappings from this map.
*/
public void clear()
{
processQueue();
hash.clear();
}
public class SoftValueHashMap extends AbstractMap implements Map {
private static class SoftValueRef extends SoftReference {
public Object key;

private SoftValueRef(Object key, Object val, ReferenceQueue q) {
super(val, q);
this.key = key;
}

private static SoftValueRef create(Object key, Object val,
ReferenceQueue q) {
if (val == null)
return null;
else
return new SoftValueRef(key, val, q);
}

}

/**
* Returns a set of the mappings contained in this hash table.
*/
public Set entrySet() {
processQueue();
return hash.entrySet();
}

/* Hash table mapping WeakKeys to values */
private Map hash;

/* Reference queue for cleared WeakKeys */
private ReferenceQueue queue = new ReferenceQueue();

/*
* Remove all invalidated entries from the map, that is, remove all entries
* whose values have been discarded.
*/
private void processQueue() {
SoftValueRef ref;
while ((ref = (SoftValueRef)queue.poll()) != null) {
if (ref == (SoftValueRef)hash.get(ref.key)) {
// only remove if it is the *exact* same WeakValueRef
//
hash.remove(ref.key);
}
}
}

/* -- Constructors -- */

/**
* Constructs a new, empty <code>WeakHashMap</code> with the given initial
* capacity and the given load factor.
*
* @param initialCapacity
* The initial capacity of the <code>WeakHashMap</code>
*
* @param loadFactor
* The load factor of the <code>WeakHashMap</code>
*
* @throws IllegalArgumentException
* If the initial capacity is less than zero, or if the load
* factor is nonpositive
*/
public SoftValueHashMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}

/**
* Constructs a new, empty <code>WeakHashMap</code> with the given initial
* capacity and the default load factor, which is <code>0.75</code>.
*
* @param initialCapacity
* The initial capacity of the <code>WeakHashMap</code>
*
* @throws IllegalArgumentException
* If the initial capacity is less than zero
*/
public SoftValueHashMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}

/**
* Constructs a new, empty <code>WeakHashMap</code> with the default
* initial capacity and the default load factor, which is <code>0.75</code>.
*/
public SoftValueHashMap() {
hash = new HashMap();
}

/**
* Constructs a new <code>WeakHashMap</code> with the same mappings as the
* specified <tt>Map</tt>. The <code>WeakHashMap</code> is created with
* an initial capacity of twice the number of mappings in the specified map
* or 11 (whichever is greater), and a default load factor, which is
* <tt>0.75</tt>.
*
* @param t the map whose mappings are to be placed in this map.
*/
public SoftValueHashMap(Map t) {
this(Math.max(2 * t.size(), 11), 0.75f);
putAll(t);
}

/* -- Simple queries -- */

/**
* Returns the number of key-value mappings in this map. <strong>Note:</strong>
* <em>In contrast with most implementations of the
* <code>Map</code> interface, the time required by this operation is
* linear in the size of the map.</em>
*/
public int size() {
processQueue();
return hash.size();
}

/**
* Returns <code>true</code> if this map contains no key-value mappings.
*/
public boolean isEmpty() {
processQueue();
return hash.isEmpty();
}

/**
* Returns <code>true</code> if this map contains a mapping for the
* specified key.
*
* @param key
* The key whose presence in this map is to be tested.
*/
public boolean containsKey(Object key) {
processQueue();
return hash.containsKey(key);
}

/* -- Lookup and modification operations -- */

/**
* Returns the value to which this map maps the specified <code>key</code>.
* If this map does not contain a value for this key, then return
* <code>null</code>.
*
* @param key
* The key whose associated value, if any, is to be returned.
*/
public Object get(Object key) {
processQueue();
SoftReference ref = (SoftReference)hash.get(key);
if (ref != null)
return ref.get();
return null;
}

/**
* Updates this map so that the given <code>key</code> maps to the given
* <code>value</code>. If the map previously contained a mapping for
* <code>key</code> then that mapping is replaced and the previous value
* is returned.
*
* @param key
* The key that is to be mapped to the given <code>value</code>
* @param value
* The value to which the given <code>key</code> is to be
* mapped
*
* @return The previous value to which this key was mapped, or
* <code>null</code> if if there was no mapping for the key
*/
public Object put(Object key, Object value) {
processQueue();
Object rtn = hash.put(key, SoftValueRef.create(key, value, queue));
if (rtn != null)
rtn = ((SoftReference)rtn).get();
return rtn;
}

/**
* Removes the mapping for the given <code>key</code> from this map, if
* present.
*
* @param key
* The key whose mapping is to be removed.
*
* @return The value to which this key was mapped, or <code>null</code> if
* there was no mapping for the key.
*/
public Object remove(Object key) {
processQueue();
return hash.remove(key);
}

/**
* Removes all mappings from this map.
*/
public void clear() {
processQueue();
hash.clear();
}
}

+ 7
- 0
src/main/javassist/scopedpool/package.html Dosyayı Görüntüle

@@ -0,0 +1,7 @@
<html>
<body>
<p>A custom class pool for several JBoss products.
It is not part of Javassist.
</p>
</body>
</html>

Loading…
İptal
Kaydet