1 package jp.sourceforge.stigmata.digger;
4 import java.util.ArrayList;
5 import java.util.Iterator;
8 import jp.sourceforge.stigmata.digger.util.WarClassLoader;
11 * Context object of Classpath.
13 * @author Haruaki TAMADA
15 public class ClasspathContext implements Iterable<URL>{
16 private ClasspathContext parent;
17 private List<URL> classpath = new ArrayList<URL>();
18 private ClassLoader loader = null;
19 private boolean includeSystemClass = true;
21 public ClasspathContext(){
25 * constructor with parent classpath context.
27 public ClasspathContext(ClasspathContext parent){
29 includeSystemClass = getParent().isIncludeSystemClasses();
33 * returns parent classpath context.
35 public ClasspathContext getParent(){
40 * If this method returns true, this object searches byte code
41 * by original ClassLoader and current ClassLoader.
42 * If this method returns false, this object searches byte code
43 * by original ClassLoader only. Not search from current ClassLoader.
45 public boolean isIncludeSystemClasses(){
46 return includeSystemClass;
50 * Set searching byte code by current ClassLoader.
51 * @see isIncludeSystemClasses
53 public synchronized void setIncludeSystemClasses(boolean flag){
54 if(includeSystemClass != flag){
57 this.includeSystemClass = flag;
59 parent.setIncludeSystemClasses(flag);
64 * adds given url to this context. If this context already has given url or
65 * parent context has given url, this method do nothing.
67 public synchronized void addClasspath(URL url){
75 * returns that this context or parent context have given url.
77 public synchronized boolean contains(URL url){
78 return (parent != null && parent.contains(url)) || classpath.contains(url);
82 * returns a size of classpath list, which this context and parent context have.
84 public synchronized int getClasspathSize(){
85 int count = classpath.size();
87 count += parent.getClasspathSize();
93 * returns an array of all of classpathes include parent context.
95 public synchronized URL[] getClasspathList(){
96 List<URL> list = new ArrayList<URL>();
100 return list.toArray(new URL[list.size()]);
104 * clears all of classpathes of this context. not clear parent context.
105 * If you want to clear this context and parent context, use {@link #clearAll <code>clearAll</code>} method.
108 public synchronized void clear(){
113 * clears all of classpathes of this context and parent context.
115 public synchronized void clearAll(){
123 * returns an iterator of classpath list.
125 public synchronized Iterator<URL> iterator(){
127 return classpath.iterator();
130 final Iterator<URL> parentIterator = parent.iterator();
131 final Iterator<URL> thisIterator = classpath.iterator();
132 return new Iterator<URL>(){
133 public boolean hasNext(){
134 boolean next = parentIterator.hasNext();
136 next = thisIterator.hasNext();
141 URL nextObject = null;
142 if(parentIterator.hasNext()){
143 nextObject = parentIterator.next();
146 nextObject = thisIterator.next();
150 public void remove(){
158 * construct and returns a ClassLoader object which loads from classpath list.
160 public synchronized ClassLoader createClassLoader(){
162 List<URL> list = new ArrayList<URL>();
167 ClassLoader parentClassLoader = null;
169 parentClassLoader = parent.createClassLoader();
172 if(isIncludeSystemClasses()){
173 parentClassLoader = getClass().getClassLoader();
176 parentClassLoader = null;
179 loader = new WarClassLoader(list.toArray(new URL[list.size()]), parentClassLoader);
185 * returns a {@link ClassFileEntry <code>ClassFileEntry</code>} object
186 * which is named given className.
188 * @return ClassFileEntry object, if not found given class, then returns null.
190 public synchronized ClassFileEntry findEntry(String className){
191 ClassLoader loader = createClassLoader();
193 URL resource = loader.getResource(className.replace('.', '/') + ".class");
195 if(resource != null){
196 return new ClassFileEntry(className, resource);
202 * returns this context has given class entry or not.
204 public synchronized boolean hasEntry(String className){
205 ClassLoader loader = createClassLoader();
206 return loader.getResource(className.replace('.', '/') + ".class") != null;
210 * finds and returns a {@link Class <code>Class</code>} object
211 * which is named given className.
213 public synchronized Class<?> findClass(String className) throws ClassNotFoundException{
215 ClassLoader loader = createClassLoader();
217 Class<?> clazz = loader.loadClass(className);
220 } catch(NoClassDefFoundError e){
221 throw new ClassNotFoundException(e.getMessage(), e);