OSDN Git Service

fed684bf3e5d77d0c1a1261eb3216c46d5a0c3d2
[stigmata/stigmata-core.git] / src / main / java / jp / naist / se / stigmata / reader / ClasspathContext.java
1 package jp.naist.se.stigmata.reader;\r
2 \r
3 /*\r
4  * $Id$\r
5  */\r
6 \r
7 import java.net.URL;\r
8 import java.util.ArrayList;\r
9 import java.util.Iterator;\r
10 import java.util.List;\r
11 \r
12 import jp.naist.se.stigmata.utils.WarClassLoader;\r
13 \r
14 /**\r
15  * @author Haruaki TAMADA\r
16  * @version $Revision$ $Date$\r
17  */\r
18 public class ClasspathContext implements Iterable<URL>{\r
19     private static ClasspathContext DEFAULT_CONTEXT = new ClasspathContext();\r
20 \r
21     private ClasspathContext parent;\r
22     private List<URL> classpath = new ArrayList<URL>();\r
23     private ClassLoader loader = null;\r
24 \r
25     private ClasspathContext(){\r
26     }\r
27 \r
28     public ClasspathContext(ClasspathContext parent){\r
29         this.parent = parent;\r
30     }\r
31 \r
32     public static final ClasspathContext getDefaultContext(){\r
33         return DEFAULT_CONTEXT;\r
34     }\r
35 \r
36     public synchronized void addClasspath(URL url){\r
37         classpath.add(url);\r
38         loader = null;\r
39     }\r
40 \r
41     public void clear(){\r
42         classpath.clear();\r
43     }\r
44 \r
45     public Iterator<URL> iterator(){\r
46         return classpath.iterator();\r
47     }\r
48 \r
49     public Iterator<URL> classpath(){\r
50         if(parent == null){\r
51             return iterator();\r
52         }\r
53         else{\r
54             final Iterator<URL> parentIterator = parent.classpath();\r
55             final Iterator<URL> thisIterator = iterator();\r
56             return new Iterator<URL>(){\r
57                 public boolean hasNext(){\r
58                     boolean next = parentIterator.hasNext();\r
59                     if(!next){\r
60                         next = thisIterator.hasNext();\r
61                     }\r
62                     return next;\r
63                 }\r
64                 public URL next(){\r
65                     URL nextObject = null;\r
66                     if(parentIterator.hasNext()){\r
67                         nextObject = parentIterator.next();\r
68                     }\r
69                     else{\r
70                         nextObject = thisIterator.next();\r
71                     }\r
72                     return nextObject;\r
73                 }\r
74                 public void remove(){\r
75                 }\r
76             };\r
77         }\r
78     }\r
79 \r
80     public synchronized ClassLoader createClassLoader(){\r
81         if(loader == null){\r
82             List<URL> list = new ArrayList<URL>();\r
83             for(Iterator<URL> i = classpath(); i.hasNext(); ){\r
84                 list.add(i.next());\r
85             }\r
86 \r
87             loader = new WarClassLoader(list.toArray(new URL[list.size()]), getClass().getClassLoader());\r
88         }\r
89         return loader;\r
90     }\r
91 \r
92     public ClassFileEntry find(String className) throws ClassNotFoundException{\r
93         ClassLoader loader = createClassLoader();\r
94 \r
95         URL resource = loader.getResource(className.replace('.', '/') + ".class");\r
96         if(resource != null){\r
97             return new ClassFileEntry(className, resource);\r
98         }\r
99         return null;\r
100     }\r
101 \r
102     public Class<?> findClass(String className) throws ClassNotFoundException{\r
103         try{\r
104             ClassLoader loader = createClassLoader();\r
105 \r
106             return loader.loadClass(className);\r
107         } catch(NoClassDefFoundError e){\r
108             throw new ClassNotFoundException(e.getMessage(), e);\r
109         }\r
110     }\r
111 }\r