* @version $Revision$
*/
public class ClasspathContext implements Iterable<URL>{
- private static ClasspathContext DEFAULT_CONTEXT = new ClasspathContext(false);
-
private ClasspathContext parent;
private List<URL> classpath = new ArrayList<URL>();
private ClassLoader loader = null;
+ private boolean includeSystemClass = true;
- /**
- * private constructor for root context.
- */
private ClasspathContext(boolean flag){
}
public ClasspathContext(){
- this(DEFAULT_CONTEXT);
+ this(new RootClasspathContext());
}
/**
*/
public ClasspathContext(ClasspathContext parent){
this.parent = parent;
+ includeSystemClass = getParent().isIncludeSystemClasses();
}
/**
}
/**
- * returns default classpath context.
+ * If this method returns true, this object searches byte code
+ * by original ClassLoader and current ClassLoader.
+ * If this method returns false, this object searches byte code
+ * by original ClassLoader only. Not search from current ClassLoader.
*/
- public static final ClasspathContext getDefaultContext(){
- return DEFAULT_CONTEXT;
+ public boolean isIncludeSystemClasses(){
+ return includeSystemClass;
+ }
+
+ /**
+ * Set searching byte code by current ClassLoader.
+ * @see isIncludeSystemClasses
+ */
+ public synchronized void setIncludeSystemClasses(boolean flag){
+ if(includeSystemClass != flag){
+ loader = null;
+ }
+ this.includeSystemClass = flag;
+ if(parent != null){
+ parent.setIncludeSystemClasses(flag);
+ }
}
/**
if(parent != null){
parentClassLoader = parent.createClassLoader();
}
+ else{
+ if(isIncludeSystemClasses()){
+ parentClassLoader = getClass().getClassLoader();
+ }
+ else{
+ parentClassLoader = ClassLoader.getSystemClassLoader();
+ }
+ }
loader = new WarClassLoader(list.toArray(new URL[list.size()]), parentClassLoader);
}
return loader;
ClassLoader loader = createClassLoader();
URL resource = loader.getResource(className.replace('.', '/') + ".class");
+
if(resource != null){
return new ClassFileEntry(className, resource);
}
try{
ClassLoader loader = createClassLoader();
- return loader.loadClass(className);
+ Class<?> clazz = loader.loadClass(className);
+
+ return clazz;
} catch(NoClassDefFoundError e){
throw new ClassNotFoundException(e.getMessage(), e);
}
}
+
+ private static class RootClasspathContext extends ClasspathContext{
+ RootClasspathContext(){
+ super(true);
+ }
+ }
}
--- /dev/null
+package jp.sourceforge.stigmata.digger;
+
+import java.io.File;
+import java.net.MalformedURLException;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClassFileEntryTest{
+ private ClasspathContext context;
+
+ @Before
+ public void setup() throws MalformedURLException{
+ context = new ClasspathContext();
+ }
+
+ @Test
+ public void testBasic() throws Exception{
+ Class<?> clazz = context.findClass("jp.sourceforge.stigmata.digger.ClasspathContext");
+ ClassFileEntry entry = context.findEntry("jp.sourceforge.stigmata.digger.ClasspathContext");
+
+ Assert.assertNotNull(clazz);
+ Assert.assertNotNull(entry);
+
+ File file = new File("target/classes/jp/sourceforge/stigmata/digger/ClasspathContext.class");
+ Assert.assertEquals("jp.sourceforge.stigmata.digger.ClasspathContext", entry.getClassName());
+ Assert.assertEquals(file.toURI().toURL(), entry.getLocation());
+ }
+}
--- /dev/null
+package jp.sourceforge.stigmata.digger;
+
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClasspathContextTest{
+ private ClasspathContext context;
+
+ @Before
+ public void setup(){
+ context = new ClasspathContext();
+ }
+
+ @Test
+ public void testBasic() throws ClassNotFoundException{
+ Class<?> classFileEntryClass = context.findClass("jp.sourceforge.stigmata.digger.ClassFileEntry");
+ Class<?> classpathContextClass = context.findClass("jp.sourceforge.stigmata.digger.ClasspathContext");
+
+ Assert.assertNotNull(classFileEntryClass);
+ Assert.assertNotNull(classpathContextClass);
+ }
+
+ @Test(expected=ClassNotFoundException.class)
+ public void testNotExistedClass() throws Exception{
+ context.findClass("not.exists.class");
+ }
+
+ @Test(expected=ClassNotFoundException.class)
+ public void testNotSearchSystemClasspath() throws Exception{
+ context.setIncludeSystemClasses(false);
+ context.findClass("jp.sourceforge.stigmata.digger.ClasspathContext");
+ }
+
+ @Test(expected=ClassNotFoundException.class)
+ public void testNotSearchSystemClasspath2() throws Exception{
+ context.addClasspath(new File("target/classes").toURI().toURL());
+ context.setIncludeSystemClasses(false);
+ // fail because classpath was not set.
+ context.findClass("org.objectweb.asm.ClassReader");
+ }
+
+ public void testNotSearchSystemClasspath3() throws Exception{
+ context.addClasspath(new File("target/classes").toURI().toURL());
+ context.setIncludeSystemClasses(false);
+ // always success to load
+ Assert.assertNotNull(context.findClass("java.lang.Object"));
+ // success because addClasspath method was called above.
+ Assert.assertNotNull(context.findClass("jp.sourceforge.stigmata.digger.ClasspathContext"));
+ }
+
+ @Test
+ public void testNotSearchSystemClasspath4() throws Exception{
+ context.addClasspath(new File("target/classes").toURI().toURL());
+ context.addClasspath(new File("target/asm-all-2.2.3.jar").toURI().toURL());
+ context.setIncludeSystemClasses(false);
+ Assert.assertNotNull(context.findClass("java.lang.Object"));
+ Assert.assertNotNull(context.findClass("jp.sourceforge.stigmata.digger.ClasspathContext"));
+ Assert.assertNotNull(context.findClass("org.objectweb.asm.ClassReader"));
+ }
+}