package net.fourbytes.shadow.mod;
/**
* A ChainClassLoader wraps itself around the class loader
* needed by the currently used backend to modify the
* behaviour of another class loader to allow dependency
* checks and loading dependencies go "down" a class loader
* chain, which means checking the children loader after the
* parent loader as long as a children loader is given.
*/
public class ChainClassLoader extends ClassLoader {
public ClassLoader chainParent;
public ClassLoader chainChild;
public String[] blacklist;
public ChainClassLoader(ClassLoader parent) {
this(parent, null, null);
}
public ChainClassLoader(ClassLoader parent, ClassLoader chainParent) {
this(parent, chainParent, null);
}
public ChainClassLoader(ClassLoader parent, ClassLoader chainParent, ClassLoader chainChild) {
super(parent);
this.chainParent = chainParent;
this.chainChild = chainChild;
}
protected synchronized Class<?> findClass(String name) throws ClassNotFoundException {
ClassLoader parent = getParent();
//Check if class blacklisted
if (blacklist != null && blacklist.length > 0) {
for (String aBlacklist : blacklist) {
if (name.equals(aBlacklist)) {
//Class is blacklisted, load it from wrapped CL
try {
return parent.loadClass(name);
} catch (ClassNotFoundException e) {
//c stays null
}
break;
}
}
}
//Load class from chain parent when c == null
if (chainParent != null) {
try {
return chainParent.loadClass(name);
} catch (ClassNotFoundException e) {
//c stays null
}
}
//Load class from chain child when c == null
if (chainChild != null) {
try {
return chainChild.loadClass(name);
} catch (ClassNotFoundException e) {
//c stays null
}
}
//Finally, check whether the wrapped CL can find the class.
//This may throw an exception.
return parent.loadClass(name);
}
}