package org.jboss.mx.loading;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.jboss.logging.Logger;
import org.jboss.mx.loading.LoadMgr3.PkgClassLoader;
import org.jboss.mx.server.ServerConstants;
public class HeirarchicalLoaderRepository3 extends UnifiedLoaderRepository3
{
private static final Logger log = Logger.getLogger(HeirarchicalLoaderRepository3.class);
private static ObjectName DEFAULT_LOADER_NAME;
static
{
try
{
DEFAULT_LOADER_NAME = new ObjectName(ServerConstants.DEFAULT_LOADER_NAME);
}
catch(Exception e)
{
log.error("Failed to initialize default loader name", e);
}
}
static class NoParentClassLoader extends ClassLoader
{
NoParentClassLoader()
{
super(HeirarchicalLoaderRepository3.class.getClassLoader());
}
public URL getResource(String name)
{
return null;
}
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
throw new ClassNotFoundException("NoParentClassLoader has no classes");
}
protected Class findClass(String name) throws ClassNotFoundException
{
throw new ClassNotFoundException("NoParentClassLoader has no classes");
}
}
static class CacheClassLoader extends UnifiedClassLoader3
{
Class cacheClass;
CacheClassLoader(Class cacheClass, LoaderRepository rep)
{
super(null, null, new NoParentClassLoader(), rep);
this.cacheClass = cacheClass;
}
protected Class findClass(String name) throws ClassNotFoundException
{
Class c = cacheClass;
if( name.equals(cacheClass.getName()) == false )
c = null;
return c;
}
}
private UnifiedLoaderRepository3 parentRepository;
private boolean java2ParentDelegation;
public HeirarchicalLoaderRepository3(UnifiedLoaderRepository3 parent)
throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException
{
this.parentRepository = parent;
}
public HeirarchicalLoaderRepository3(MBeanServer server)
throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException
{
this(server, DEFAULT_LOADER_NAME);
}
public HeirarchicalLoaderRepository3(MBeanServer server, ObjectName parentName)
throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException
{
this.parentRepository = (UnifiedLoaderRepository3) server.getAttribute(parentName,
"Instance");
}
public RepositoryClassLoader newClassLoader(final URL url, boolean addToRepository)
throws Exception
{
UnifiedClassLoader3 ucl = null;
if( java2ParentDelegation == false )
ucl = new UnifiedClassLoader3(url, null, new NoParentClassLoader(), this);
else
ucl = new UnifiedClassLoader3(url, null, this);
if( addToRepository )
{
this.addClassLoader(ucl);
}
return ucl;
}
public RepositoryClassLoader newClassLoader(final URL url, final URL origURL, boolean addToRepository)
throws Exception
{
UnifiedClassLoader3 ucl = null;
if( java2ParentDelegation == false )
ucl = new UnifiedClassLoader3(url, origURL, new NoParentClassLoader(), this);
else
ucl = new UnifiedClassLoader3(url, origURL, this);
if( addToRepository )
{
this.addClassLoader(ucl);
}
return ucl;
}
public boolean getUseParentFirst()
{
return java2ParentDelegation;
}
public void setUseParentFirst(boolean flag)
{
java2ParentDelegation = flag;
}
public Class loadClass(String name, boolean resolve, ClassLoader scl)
throws ClassNotFoundException
{
Class foundClass = null;
if( java2ParentDelegation == true )
{
try
{
foundClass = parentRepository.loadClass(name, resolve, scl);
}
catch(ClassNotFoundException e)
{
if( foundClass == null )
foundClass = super.loadClass(name, resolve, scl);
}
}
else
{
try
{
foundClass = super.loadClass(name, resolve, scl);
}
catch(ClassNotFoundException e)
{
if( foundClass == null )
foundClass = parentRepository.loadClass(name, resolve, scl);
}
}
if( foundClass != null )
return foundClass;
throw new ClassNotFoundException(name);
}
public Class getCachedClass(String classname)
{
Class clazz = null;
if( java2ParentDelegation == true )
{
clazz = parentRepository.getCachedClass(classname);
if( clazz == null )
clazz = super.getCachedClass(classname);
}
else
{
clazz = super.getCachedClass(classname);
}
return clazz;
}
public URL getResource(String name, ClassLoader scl)
{
URL resource = null;
if( java2ParentDelegation == true )
{
resource = getParentResource(name, scl);
if( resource == null )
resource = super.getResource(name, scl);
}
else
{
resource = super.getResource(name, scl);
if( resource == null )
{
resource = getParentResource(name, scl);
}
}
return resource;
}
public void getResources(String name, ClassLoader cl, List urls)
{
if( java2ParentDelegation == true )
{
parentRepository.getResources(name, cl, urls);
super.getResources(name, cl, urls);
}
else
{
super.getResources(name, cl, urls);
parentRepository.getResources(name, cl, urls);
}
}
public URL[] getURLs()
{
URL[] ourURLs = super.getURLs();
URL[] parentURLs = parentRepository.getURLs();
int size = ourURLs.length + parentURLs.length;
URL[] urls = new URL[size];
System.arraycopy(ourURLs, 0, urls, 0, ourURLs.length);
System.arraycopy(parentURLs, 0, urls, ourURLs.length, parentURLs.length);
return urls;
}
public Class loadClassFromCache(String name)
{
Class foundClass = null;
if( java2ParentDelegation == true )
{
foundClass = parentRepository.loadClassFromCache(name);
if( foundClass == null )
foundClass = super.loadClassFromCache(name);
}
else
{
foundClass = super.loadClassFromCache(name);
}
return foundClass;
}
public Set getPackageClassLoaders(String name)
{
Set pkgSet = super.getPackageClassLoaders(name);
Set parentPkgSet = parentRepository.getPackageClassLoaders(name);
GetClassLoadersAction action = new GetClassLoadersAction(name, pkgSet,
parentPkgSet);
Set theSet = (Set) AccessController.doPrivileged(action);
return theSet;
}
public int compare(LoaderRepository lr)
{
if (lr == this)
return 0;
return reverseCompare(lr);
}
protected int reverseCompare(LoaderRepository lr)
{
if (lr != parentRepository)
return 0;
if (java2ParentDelegation)
return +1;
else
return -1;
}
private URL getParentResource(String name, ClassLoader scl)
{
URL resource = parentRepository.getResourceFromGlobalCache(name);
if( resource != null )
return resource;
resource = parentRepository.getResourceFromRepository(name, scl);
return resource;
}
private class GetClassLoadersAction implements PrivilegedAction
{
private String name;
Set pkgSet;
Set parentPkgSet;
GetClassLoadersAction(String name, Set pkgSet, Set parentPkgSet)
{
this.name = name;
this.pkgSet = pkgSet;
this.parentPkgSet = parentPkgSet;
}
public Object run()
{
Set theSet = ClassLoaderUtils.newPackageSet();
if( pkgSet != null )
{
Iterator iter = pkgSet.iterator();
while( iter.hasNext() )
{
RepositoryClassLoader ucl = (RepositoryClassLoader) iter.next();
PkgClassLoader pkgUcl = new PkgClassLoader(ucl, 0);
theSet.add(pkgUcl);
}
}
if( java2ParentDelegation == false )
{
Class cacheClass = parentRepository.loadClassFromCache(name);
if( cacheClass != null )
{
RepositoryClassLoader ucl = new CacheClassLoader(cacheClass, HeirarchicalLoaderRepository3.this);
PkgClassLoader pkgUcl = new PkgClassLoader(ucl, 1);
theSet.add(pkgUcl);
}
}
if( parentPkgSet != null )
{
Iterator iter = parentPkgSet.iterator();
while( iter.hasNext() )
{
RepositoryClassLoader ucl = (RepositoryClassLoader) iter.next();
PkgClassLoader pkgUcl = new PkgClassLoader(ucl, 2);
theSet.add(pkgUcl);
}
}
if( java2ParentDelegation == false )
{
ClassLoader loader = RepositoryClassLoader.class.getClassLoader();
RepositoryClassLoader ucl = null;
if( loader instanceof RepositoryClassLoader )
ucl = (RepositoryClassLoader) loader;
else
ucl = new UnifiedClassLoader3(null, null, HeirarchicalLoaderRepository3.this);
PkgClassLoader pkgUcl = new PkgClassLoader(ucl, 3);
theSet.add(pkgUcl);
}
return theSet;
}
}
}