package org.marketcetera.module;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.log.SLF4JLoggerProxy;
import java.util.regex.Pattern;
import java.util.Enumeration;
import java.net.URL;
import java.io.IOException;
/* $License$ */
/**
* This class loader is used to test class/resource loading failures
* when loading module factories, etc.
*
* Classes that match {@link #getFailClasses()} value, if it is set,
* fail to load with a ClassNotFoundException.
*
* Requested resources whose names match {@link #getFailResources()} value, if
* it is set, are not found. ie. empty enumerations are returned for them from
* {@link ClassLoader#getResources(String)}
*
* Found resources whose names match {@link #getFilterResources()} are
* filtered out from enumerations returned from {@link ClassLoader#getResources(String)}
*
* @author anshul@marketcetera.com
*/
@ClassVersion("$Id: ModuleTestClassLoader.java 16154 2012-07-14 16:34:05Z colin $")
class ModuleTestClassLoader extends ClassLoader{
/**
* Creates an instance.
*
* @param parent the parent classloader.
*/
public ModuleTestClassLoader(ClassLoader parent) {
super(parent);
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if(mFailResources != null && mFailResources.matcher(name).matches()) {
SLF4JLoggerProxy.info(this, "Ignoring matched resource {}", name);
return new Enumeration<URL>(){
public boolean hasMoreElements() {
return false;
}
public URL nextElement() {
return null;
}
};
}
SLF4JLoggerProxy.info(this, "Finding resources {}", name);
final Enumeration<URL> resources = super.getResources(name);
return new Enumeration<URL>() {
public boolean hasMoreElements() {
while(resources.hasMoreElements()) {
mNext = resources.nextElement();
if(mFilterResources == null ||
!mFilterResources.matcher(
mNext.toString()).matches()) {
return true;
} else {
SLF4JLoggerProxy.info(this, "Ignoring URL {}", mNext);
}
}
return false;
}
public URL nextElement() {
SLF4JLoggerProxy.info(this, "Returning URL {}", mNext);
return mNext;
}
private URL mNext;
};
}
/**
* Pattern for resources that should not be found.
*
* @return pattern for resources that should not be found.
*/
public Pattern getFailResources() {
return mFailResources;
}
/**
* Pattern for resources that should not be found.
*
* @param inFailResources pattern for resources that should
* not be found, can be null.
*/
public void setFailResources(Pattern inFailResources) {
mFailResources = inFailResources;
}
/**
* The pattern for classes that should fail to load.
*
* @return pattern for classes that should fail to load.
*/
public Pattern getFailClasses() {
return mFailClasses;
}
/**
* The pattern for classes that should fail to load.
*
* @param inFailClasses pattern for classes that should fail
* to load, can be null.
*/
public void setFailClasses(Pattern inFailClasses) {
mFailClasses = inFailClasses;
}
/**
* Returns the resource filter.
*
* @return the resource filter.
*/
public Pattern getFilterResources() {
return mFilterResources;
}
/**
* Sets the resource filter.
*
* @param inFilterResources the resource filter, can be null.
*/
public void setFilterResources(Pattern inFilterResources) {
mFilterResources = inFilterResources;
}
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
if(mFailClasses!= null && mFailClasses.matcher(name).matches()) {
SLF4JLoggerProxy.info(this, "Ignoring matched class {}", name);
throw new ClassNotFoundException("Sorry!");
}
SLF4JLoggerProxy.info(this, "Fetching class {}", name);
return super.loadClass(name, resolve);
}
private Pattern mFailClasses;
private Pattern mFailResources;
private Pattern mFilterResources;
}