1 package jp.naist.se.stigmata.reader;
\r
8 import java.util.ArrayList;
\r
9 import java.util.Iterator;
\r
10 import java.util.List;
\r
12 import jp.naist.se.stigmata.utils.WarClassLoader;
\r
15 * @author Haruaki TAMADA
\r
16 * @version $Revision$ $Date$
\r
18 public class ClasspathContext implements Iterable<URL>{
\r
19 private static ClasspathContext DEFAULT_CONTEXT = new ClasspathContext(false);
\r
21 private ClasspathContext parent;
\r
22 private List<URL> classpath = new ArrayList<URL>();
\r
23 private ClassLoader loader = null;
\r
26 * private constructor for root context.
\r
28 private ClasspathContext(boolean flag){
\r
31 public ClasspathContext(){
\r
32 this(DEFAULT_CONTEXT);
\r
36 * constructor with parent classpath context.
\r
38 public ClasspathContext(ClasspathContext parent){
\r
39 this.parent = parent;
\r
43 * returns parent classpath context.
\r
45 public ClasspathContext getParent(){
\r
50 * returns default classpath context.
\r
52 public static final ClasspathContext getDefaultContext(){
\r
53 return DEFAULT_CONTEXT;
\r
57 * adds given url to this context. If this context already has given url or
\r
58 * parent context has given url, this method do nothing.
\r
60 public synchronized void addClasspath(URL url){
\r
68 * returns that this context or parent context have given url.
\r
70 public synchronized boolean contains(URL url){
\r
71 return (parent != null && parent.contains(url)) || classpath.contains(url);
\r
75 * returns a size of classpath list, which this context and parent context have.
\r
77 public int getClasspathSize(){
\r
78 int count = classpath.size();
\r
80 count += parent.getClasspathSize();
\r
86 * returns an array of all of classpathes include parent context.
\r
88 public synchronized URL[] getClasspathList(){
\r
89 List<URL> list = new ArrayList<URL>();
\r
93 return list.toArray(new URL[list.size()]);
\r
97 * clears all of classpathes of this context. not clear parent context.
\r
98 * If you want to clear this context and parent context, use {@link #clearAll <code>clearAll</code>} method.
\r
101 public void clear(){
\r
106 * clears all of classpathes of this context and parent context.
\r
108 public void clearAll(){
\r
110 if(parent != null){
\r
115 public Iterator<URL> iterator(){
\r
116 if(parent == null){
\r
117 return classpath.iterator();
\r
120 final Iterator<URL> parentIterator = parent.iterator();
\r
121 final Iterator<URL> thisIterator = classpath.iterator();
\r
122 return new Iterator<URL>(){
\r
123 public boolean hasNext(){
\r
124 boolean next = parentIterator.hasNext();
\r
126 next = thisIterator.hasNext();
\r
131 URL nextObject = null;
\r
132 if(parentIterator.hasNext()){
\r
133 nextObject = parentIterator.next();
\r
136 nextObject = thisIterator.next();
\r
140 public void remove(){
\r
146 public synchronized ClassLoader createClassLoader(){
\r
147 if(loader == null){
\r
148 List<URL> list = new ArrayList<URL>();
\r
149 for(URL url: this){
\r
153 loader = new WarClassLoader(list.toArray(new URL[list.size()]), getClass().getClassLoader());
\r
158 public ClassFileEntry find(String className) throws ClassNotFoundException{
\r
159 ClassLoader loader = createClassLoader();
\r
161 URL resource = loader.getResource(className.replace('.', '/') + ".class");
\r
162 if(resource != null){
\r
163 return new ClassFileEntry(className, resource);
\r
168 public Class<?> findClass(String className) throws ClassNotFoundException{
\r
170 ClassLoader loader = createClassLoader();
\r
172 return loader.loadClass(className);
\r
173 } catch(NoClassDefFoundError e){
\r
174 throw new ClassNotFoundException(e.getMessage(), e);
\r